package com.example.springsecuritydemo.security;

import com.example.springsecuritydemo.entities.SecurityUser;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author lzy
 * @date 2021-06-25 下午12:05
 */
@Component
public class TokenManager {
    public static final String AUTH_PREFIX_LOGIN = "login_token_%s";
    private final CacheManager cacheManager;
    private final Cache tokenCache;

    public TokenManager() {
        this.cacheManager = new CacheManager();
        this.tokenCache = cacheManager.getCache("sessionCache");
    }

    /**
     * Create token string.
     * 这里采用透明缓存
     *
     * @param user the user
     * @return the string
     */
    public String createToken(SecurityUser user) {
        final String token = String.format(AUTH_PREFIX_LOGIN, UUID.randomUUID());
        synchronized (this) {
            // 不允许重复登录
            removeTokenByUsername(user.getUsername());
            Element element = new Element(token, user);
            tokenCache.put(element);
        }
        return token;
    }

    /**
     * Gets user by token.
     *
     * @param token the token
     * @return the user by token
     */
    public Optional<SecurityUser> getUserByToken(String token) {
        final Element element = tokenCache.get(token);
        return Optional.ofNullable(element)
                .map(ele -> (SecurityUser) ele.getObjectValue());
    }

    /**
     * 根据登录名移除缓存中的即有项
     * Remove token.
     *
     * @param username the username
     */
    public void removeTokenByUsername(String username) {
        tokenCache.getKeys().forEach(key -> {
            final Element element = tokenCache.get(key);
            SecurityUser user = (SecurityUser) element.getObjectValue();
            if (user.getUsername().equals(username)) {
                tokenCache.remove(key);
            }
        });
    }

    public void removeToken(String token) {
        tokenCache.remove(token);
    }
}
